import React, { useEffect, useState } from 'react';
import { Modal, Form, Input, Switch, message } from 'antd';
 
import { getToken } from '@/utils/myAuth';
import { connect } from 'umi';
import type { Dispatch, ArticleType } from 'umi';

import type { ConnectState } from '@/models/connect';
import type { StateType as MStateType } from './model';
// loading组件
import { PageLoading } from '@ant-design/pro-layout';
// 引入自定义组件
import CoverImgUpload from './CoverImgUpload';
// 引入通用富文本组件
import CommonBraftEditor from '@/components/CommonBraftEditor';

type PropsType = {
  isModalVisible: boolean;
  setIsModalVisible: any; // ??
  dispatch: Dispatch;
  refrushList: any;
  id: string;
  article: ArticleType;
  loading: boolean;
};
const namespace = 'articleEdit';


const ArticleEdit: React.FC<PropsType> = (props) => {
  // 声明响应式属性 默认false 状态被提升到父组件 进行控制
  // const [isModalVisible,setIsModalVisible] = useState(true);
  // props属性从哪来的,就要回哪进行修改
  const { isModalVisible, setIsModalVisible, id, article, loading, dispatch, refrushList } = props;
  // 获取form组件
  const [form] = Form.useForm();
  // 定义上传的图片
  const [coverImg, setCoverImg] = useState<string>('');
  // 定义富文本内容
  const [content, setContent] = useState<string>('');
  // 测试清空表单
  const doClearForm = () => {
    // 1. setFieldsValue 设置表单不是还原
    // 1.1 resetFields() 用于清空表单
    form.resetFields();
    // 2  清空上传的组件 ???
    // 2.1 需要把Upload变为受控组件 文件都在fileList做关联
    setCoverImg(''); // 需要再单独清空coverImg字段
    // 因为这里不需要article了 所以可以对article进行重置
    dispatch({
      type: `${namespace}/setArticle`,
      payload: {
        article: {
          author: '',
          title: '',
        }
      }
    })
  };

  const callback = () => {
    // console.log('回调了...');
    doClearForm();
    // 2. 关闭表单
    setIsModalVisible(false);
    // 3. 刷新列表
    refrushList();
  };
  const handleOk = () => {
    // 1. 对form进行验证
    form
      .validateFields()
      .then(() => {
        // console.log('ok')
        // 2. 获取表单值
        const formValues = form.getFieldsValue();
        // 测试下提交的数据对象是否符合需求
        const submitFormValue = {
          ...formValues,
          isShow: formValues.isShow ? '1' : '0',
          coverImg,
          content1: content,
          content2: content,
          editorType: '0', // 富文本类型 先默认0
        };
        // 因为没有手动添加id 导致一直都是addArticle接口
        if (id) {
          submitFormValue.id = id;
        }
        // console.log(submitFormValue);
        // 3. 提交表单
        dispatch({
          type: `${namespace}/saveArticle`,
          payload: {
            submitFormValue,
            callback,
          },
        });
      })
      .catch((err) => {
        message.error('请注意表单验证!');
        console.log(err);
      });
  };
  const handleCancel = () => {
    // 清空表单
    doClearForm();
    setIsModalVisible(false);
  };
  const onIsShowSwitchChange = () => {};
  
  // 用于处理封面图片上传成功的回调
  const coverImgUploadChange = (fileUrl: string)=>{
    // console.log(fileUrl);
    // 得到了上传后的回调结果,需要构建成新的表单数据
    setCoverImg(fileUrl);
  }
  // 用于处理编辑器变化的回调
  const handleEditorChange = (value: string)=>{
    console.log('编辑器内容:',value);
    // 用于存储内容,用于提交的时候构建表单
    setContent(value);
  }
  // 应该在id被赋值的时候 触发请求
  // bug: 如果两次打开相同的id,则当前effect不会触发!
  // useEffect(() => {
  //   if (id) {
  //     dispatch({
  //       type: `${namespace}/findArticle`,
  //       payload: {
  //         id,
  //       },
  //     });
  //   }
  // }, [id]);
  useEffect(()=>{
    if(isModalVisible){
      if (id) {
        dispatch({
          type: `${namespace}/findArticle`,
          payload: {
            id,
          },
        });
    }
    }
  },[isModalVisible])
  // 如果article被赋值 需要重新填写表单
  useEffect(() => {
    // 判断是否真实的获取到了article,获取到了再填写表单
    if (article.id) {
      const formData = {
        ...article,
        isShow: article.isShow === 1, // isShow是true/false,所以需要转换
      };
      // 表单赋值
      form.setFieldsValue({
        ...formData,
      });
      
      setCoverImg(article.coverImg||''); // 用于更新表单字段值
    }
  }, [article]);
  return (
    <Modal
      width="60%"
      title="编辑文章"
      visible={isModalVisible}
      onOk={handleOk}
      onCancel={handleCancel}
    >
      {loading ? (
        <PageLoading />
      ) : (
        <Form
          form={form}
          labelCol={{ span: 4 }}
          wrapperCol={{ span: 20 }}
          initialValues={{
            isShow: true,
          }}
        >
          <Form.Item
            label="文章标题"
            name="title"
            rules={[{ required: true, message: '必须输入文章标题!' }]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label="作者"
            name="author"
            rules={[{ required: true, message: '必须输入作者名称!' }]}
          >
            <Input />
          </Form.Item>
          <Form.Item label="文章概要" name="summary">
            <Input.TextArea rows={2} />
          </Form.Item>
          {/* valuePropName 意思是: 当前Form.Item 的name是isShow,但是需要按照switch的checked值进行映射 */}
          <Form.Item label="是否显示" name="isShow" valuePropName="checked">
            <Switch defaultChecked onChange={onIsShowSwitchChange} />
          </Form.Item>
          <Form.Item label="封面图片">
            <CoverImgUpload action="/lejuAdmin/material/uploadFileOss" 
              token={getToken()||''} 
              onChange={coverImgUploadChange}
              coverImg={coverImg}
              />
          </Form.Item>
          <Form.Item label="文章内容"></Form.Item>
          <CommonBraftEditor onChange={handleEditorChange} value={article.content1||''} uploadUrl={"/lejuAdmin/material/uploadFileOss"} token={getToken()||''}/>
        </Form>
      )}
    </Modal>
  );
};
type StateType = {
  [namespace]: MStateType;
} & ConnectState;
// 以上等价于下面这个类型
// type StateType ={
//   global: GlobalModelState;
//   loading: Loading;
//   settings: ProSettings;
//   user: UserModelState;
//   login: StateType;
//   articleEdit: MStateType;
// };
const mapStateToProps = (state: StateType) => ({
  article: state[namespace].article,
  loading: state.loading.effects[`${namespace}/findArticle`] as boolean,
});

export default connect(mapStateToProps)(ArticleEdit);
